package com.ocom.payhandle.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.HttpUtils;
import com.ocom.common.constant.PayHandleUrl;
import com.ocom.common.entity.card.EntityXfRecord;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.entity.card.EntiyXfMerchPayInfo;
import com.ocom.common.entity.master.EntityCompanyList;
import com.ocom.common.entity.pay.EntityAbnormal;
import com.ocom.common.enums.PayWar;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.payhandle.feign.XfRecordFeign;
import com.ocom.payhandle.fun.PayHandleFunService;
import com.ocom.payhandle.mq.business.saveorder.SaveOrderProductService;
import com.ocom.payhandle.service.AbnormalService;
import com.ocom.payhandle.service.CompanyInfoService;
import com.ocom.payhandle.service.XfMerchPayInfoService;
import com.ocom.payhandle.service.XfRecordProcessService;
import com.ocom.payhandle.vo.MqSaveOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 对账 同步
 */
@Slf4j
@RestController
public class ReconciliationController {

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private AbnormalService abnormalService;

    @Autowired
    private XfRecordProcessService xfRecordProcessService;

    @Autowired
    private SaveOrderProductService saveOrderProductService;

    @Autowired
    private XfRecordFeign xfRecordFeign;

    @Autowired
    private XfMerchPayInfoService xfMerchPayInfoService;

    private static String url = "";

    //1. 退款定时任务
    @GetMapping(PayHandleUrl.URL_syncRefundOrder)
    public Result syncRefundOrder() {
        log.info("定时任务-退款查询");
        refundOrder(1l);
        refundOrder(600l);
        return ResultUtil.success();
    }


    //更新某天
    //2.迁移的定时任务
    @PostMapping(PayHandleUrl.URL_syncMqFailOrder)
    public Result syncMqFailOrder(@RequestParam(required = false) String day) {
        log.info("定时任务-迁移mq");
        if (CommonUtil.isNull(day)) {
            Date date = new Date();
            day = DateUtil.getStrDate(date, "yyyy-MM-dd");

            revOrder(1l, day);
            revOrder(600l, day);

            Date date2 = DateUtil.addDays(new Date(), -1);
            String day2 = DateUtil.getStrDate(date2, "yyyy-MM-dd");

            revOrder(1l, day2);
            revOrder(600l, day2);

            Date date3 = DateUtil.addDays(new Date(), -2);
            String day3 = DateUtil.getStrDate(date3, "yyyy-MM-dd");

            revOrder(1l, day3);
            revOrder(600l, day3);

            return ResultUtil.success();
        }
        revOrder(1l, day);
        revOrder(600l, day);


        return ResultUtil.success();
    }

    private void revOrder(Long comId, String day) {
        try {
            List<EntityAbnormal> entityAbnormals = abnormalService.getAbnormalList(comId, day);
            List<String> Ids = entityAbnormals.stream().map(EntityAbnormal::getPlatOrderNo).collect(Collectors.toList());

            if (Ids == null || Ids.size() <= 0) {
                return;
            }

            List<Integer> codesInteger = Ids.stream().map(Integer::parseInt).collect(Collectors.toList());

            List<EntityXfRecordProcess> entityXfRecordProcessList = xfRecordProcessService.getMqFailList(comId, codesInteger);

            for (EntityXfRecordProcess entityXfRecordProcess : entityXfRecordProcessList) {
                try {
                    MqSaveOrderVo mqSaveOrderVo = new MqSaveOrderVo();
                    mqSaveOrderVo.setComId(entityXfRecordProcess.getComId());
                    mqSaveOrderVo.setId(entityXfRecordProcess.getId());
                    mqSaveOrderVo.setMachNo(entityXfRecordProcess.getDeviceNo());
                    mqSaveOrderVo.setType(1);
                    saveOrderProductService.saveOrder(JSON.toJSONString(mqSaveOrderVo));
                } catch (Exception e) {
                    StackTraceElement ste = e.getStackTrace()[0];
                    log.info("请求方式mq:【{}】,机器号:【{}】,插入mq推送异常:【{}】,异常的返回:【{}】,行号:【{}】", "支付请求（强在线）", entityXfRecordProcess.getDeviceNo(), entityXfRecordProcess, e, ste.getLineNumber());
                }
            }

        } catch (Exception e) {
            log.error("定时同步mq失败订单异常 【{}】", e);
        }

    }

    private void refundOrder(Long comId) {
        try {
            List<EntityXfRecordProcess> entityXfRecordProcessList = xfRecordProcessService.getRefundOrders(comId);

            if (entityXfRecordProcessList == null || entityXfRecordProcessList.size() <= 0) {
                return;
            }

            for (EntityXfRecordProcess entityXfRecordProcess : entityXfRecordProcessList) {
                try {

                    EntiyXfMerchPayInfo entiyXfMerchPayInfo = xfMerchPayInfoService.selectConfigure(entityXfRecordProcess.getComId(), entityXfRecordProcess.getPayChannelNo());
                    if (entiyXfMerchPayInfo == null) continue;

                    /**
                     * {
                     *     "company_id":"20200220001",
                     *     "user_name":"alibaba",
                     *     "password":"123456",
                     *     "out_trade_no":"20200225005",
                     *     "refund_trade_no":"202002250051"
                     * }
                     */


                    Map<String, Object> retMap = new HashMap<>();
                    retMap.put("company_id", entiyXfMerchPayInfo.getCompanyId());
                    retMap.put("user_name", entiyXfMerchPayInfo.getUserName());
                    retMap.put("password", entiyXfMerchPayInfo.getPassword());
                    retMap.put("out_trade_no", entityXfRecordProcess.getOrigOrderNo());
                    retMap.put("refund_trade_no", entityXfRecordProcess.getOrderNo());


                    String payUrl = companyInfoService.getPayCenterUrl(entityXfRecordProcess.getComId(), entiyXfMerchPayInfo.getCompanyId());
                    String json = HttpUtils.postJson(payUrl + "/unifiedmicropay/refundQuery", retMap);
                    JSONObject results = JSON.parseObject(json);

                    if (results.getInteger("code") != 200) continue;

                    log.info("退款定时任务查询【{}】【{}】", retMap, json);
                    //支付成功，修改等待表的状态和把数据入成功表
                    Map<String, String> dataMap = (Map<String, String>) JSON.parse(results.getString("data"));

                    /**
                     * {
                     * 	"msg": "success",
                     * 	"code": 200,
                     * 	"data": {
                     * 		"trade_status": "SUCCESS",
                     * 		"trade_state_desc": "SUCCESS",
                     * 		"out_trade_no": "671533911711086886635",
                     * 		"refund_trade_no": "671533911711086902624",
                     * 		"refund_time": "2024-03-22 13:55:04",
                     * 		"refund_money": 6600
                     *    }
                     * }
                     */

                    //如果统一支付返回成功
                    String refundOrderNO = dataMap.get("refund_trade_no");
                    String origOrderNO = dataMap.get("out_trade_no");
                    Date date = DateUtils.strToDate(dataMap.get("refund_time"));

                    try {
                        xfRecordProcessService.refundHandle(entityXfRecordProcess.getComId(),
                                entityXfRecordProcess.getDeviceNo(),
                                origOrderNO,
                                refundOrderNO,
                                date
                        );
                    } catch (Exception e) {
                        StackTraceElement ste = e.getStackTrace()[0];
                        log.info("退款事务失败:【{}】,机器号:【{}】,退款查询定时任务:【{}】,异常的返回:【{}】,行号:【{}】", "退款查询（定时任务）", entityXfRecordProcess.getDeviceNo(), entityXfRecordProcess, e, ste.getLineNumber());
                        continue;
                    }
                    //成功库订单修改为已退款
                    EntityXfRecordProcess entityXfRecordProcessOrg = xfRecordProcessService.selectTradeNo(entityXfRecordProcess.getComId(), origOrderNO, null);
                    if (entityXfRecordProcess != null) {
                        EntityXfRecord entityXfRecord = JSON.parseObject(JSON.toJSONString(entityXfRecordProcessOrg), EntityXfRecord.class);
                        Result result = xfRecordFeign.updateXfRecord(entityXfRecord);
                        if (result.getCode() != 200) {
                            //记录异常
                            EntityAbnormal entityAbnormal = new EntityAbnormal();
                            entityAbnormal.setComId(entityXfRecord.getComId());
                            entityAbnormal.setPlatOrderNo(entityXfRecordProcessOrg.getId().toString());
                            //1.回调异常记录
                            entityAbnormal.setType(3);
                            entityAbnormal.setRemark("修改成功库退款失败");
                            abnormalService.Add(entityXfRecord.getComId(), entityAbnormal);
                        }
                    }

//                    EntityXfRecordProcess entityXfRecordProcess2 = xfRecordProcessService.selectTradeNo(entityXfRecordProcess.getComId(), entityXfRecordProcess.getId());
//                    EntityXfRecord entityXfRecord = JSONObject.parseObject(JSON.toJSONString(entityXfRecordProcess2), EntityXfRecord.class);
//                    entityXfRecord.setPayState(1);
//                    xfRecordFeign.sveXfRecord(entityXfRecord);
                    try {
                        MqSaveOrderVo mqSaveOrderVo = new MqSaveOrderVo();
                        mqSaveOrderVo.setComId(entityXfRecordProcess.getComId());
                        mqSaveOrderVo.setId(entityXfRecordProcess.getId());
                        mqSaveOrderVo.setMachNo(entityXfRecordProcess.getDeviceNo());
                        mqSaveOrderVo.setType(0); //正常迁移
                        saveOrderProductService.saveOrder(JSON.toJSONString(mqSaveOrderVo));
                    } catch (Exception e) {
                        StackTraceElement ste = e.getStackTrace()[0];
                        log.info("请求方式mq2:【{}】,机器号:【{}】,插入mq推送异常:【{}】,异常的返回:【{}】,行号:【{}】", "支付请求（强在线）", entityXfRecordProcess.getDeviceNo(), entityXfRecordProcess, e, ste.getLineNumber());
                    }

                } catch (Exception e) {
                    StackTraceElement ste = e.getStackTrace()[0];
                    log.info("请求方式mq:【{}】,机器号:【{}】,退款查询定时任务:【{}】,异常的返回:【{}】,行号:【{}】", "退款查询（定时任务）", entityXfRecordProcess.getDeviceNo(), entityXfRecordProcess, e, ste.getLineNumber());
                }
            }
        } catch (Exception e) {
            log.error("退款查询定时任务异常 【{}】", e);
        }

    }
}
